from types import MethodType


class Student(object):
    pass


s = Student()
s.name = 'Michael'
print(s.name)


def set_age(self, age):
    self.age = age


s.set_age = MethodType(set_age, s)

s.set_age(25)
print(s.age)

# 给一个实例绑定的方法，对另一个实例是不起作用的：
s2 = Student()

try:
    s2.set_age(25)
except:
    pass



# 为了给所有实例都绑定方法，可以给class绑定方法：
def set_score(self, score):
    self.score = score


Student.set_score = set_score

s.set_score(108)
print(s.score)
s2.set_score(110)
print(s2.score)

# 上面的set_score方法可以直接定义在class中，
# 但动态绑定允许我们在程序运行的过程中动态给class加上功能，
# 这在静态语言中很难实现。


# 我们想要限制实例的属性怎么办
# 使用__slots__


class Student2(object):
    __slots__ = ('name', 'age')

ss = Student2()

ss.name = 'Michael'
ss.age = 25
# ss.score = 108

# 使用__slots__要注意，__slots__定义的属性仅对当前类实例起作用，
# 对继承的子类是不起作用的：

class GraduateStudent(Student2):
    __slots__ = ('score',)
    pass


g = GraduateStudent()
g.score = 999
g.name = 'zhangsan'
g.age = 18

g.gender='female'


# 除非在子类中也定义__slots__，这样，
# 子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。